package material.iteratorAndComponent.iteratorAndComponent;
import java.util.Iterator;

import java.util.Stack;

public class CompositeIterator implements Iterator {
    Stack stack = new Stack();

    /**
     * 我们将要遍历的顶层组合的迭代器传入
     * 我们把它抛进一个堆栈数据结构中
     *
     * @param iterator
     */
    public CompositeIterator(Iterator iterator) {
        stack.push(iterator);
    }

    @Override
    public boolean hasNext() {
        /**
         * 想要知道是否还有下一个元素，我们检查堆栈是否被清空
         * 如果已经空了，就表示没有下一个元素了
         */
        if (stack.empty()) {
            return false;
        } else {
            /**
             * 否则我们从栈顶元素中取出迭代器
             * 看看是否还有下一个元素
             * 如果他没有元素，我们将它弹出堆栈，然后递归调用next()
             */
            Iterator iterator = (Iterator) stack.peek();//stack.peek()和stack.popo()均是从栈顶取值，不同的是pop会删除栈顶元素，而peek不会
            if (!iterator.hasNext()) {
                stack.pop();
                return hasNext();
            } else return true;
        }
    }

    @Override
    public Object next() {
        /**
         * 当客户想要取得下一个元素的时候，我们先调用hasNext()来确定是否还有下一个
         */
        if (hasNext()) {
            Iterator iterator = (Iterator) stack.peek();
            MenuComponent component = (MenuComponent) iterator.next();
            /**
             * 如果元素是一个菜单，我们有了另一个需要被包含进遍历中的组合
             * 所以我们需要将它丢进堆栈中，不管是否是菜单，我们都返回此组件
             * **/
            if (component instanceof Menu) {
                stack.push(((Menu) component).createIterator());
            }
            return component;
        } else return null;
    }

    /**
     * 此处设置为不允许删除
     */
    public void remove() {
        throw new UnsupportedOperationException();
    }
}
